﻿using STHPMS1.BLL.B_Core;
using STHPMS1.Common.C_Entity.Stmpms1;
using STHPMS1.Common.C_Enum;
using STHPMS1.ICore;
using STHPMS1.ICore.I_BLL.Bus;
using STHPMS1.ICore.I_Entity.Info;
using STHPMS1.ICore.I_Entity.Stmpms1;
using STHPMS1.ICore.I_Serv;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using STHPMS1.Common.C_Extension;
using STHPMS1.ICore.I_DAL;
using System.Data;
using System.Linq;
using STHPMS1.Common.C_Utils;
using STHPMS1.Common.C_Entity;
using STHPMS1.BLL.B_Serv;

namespace STHPMS1.BLL.B_Bus
{
    public class B_InvntoryBus : BllBase, IB_InvntoryBill
    {
        public void Save<T>(T entity)
            where T : class ,IB_Invntory
        {
            this.Scene.Dal.Sthpms1.Save(entity);
        }

        public void Remove(IB_Invntory entity)
        {
            this.Scene.Dal.Sthpms1.DeleteById<B_Invntory>(entity.Segid);
        }

        public IEnumerable<T> Get<T>(Expression<Func<T, bool>> predicate, IPagingInfo info)
            where T : class, IB_Invntory
        {
            return this.Scene.Dal.Sthpms1.Select<T>(predicate, info);
        }

        public DataTable GetRoadDivisionResult(IPagingInfo info)
        {
            DataTable dt = this.Scene.Dal.Sthpms1.B_Invntory.GetRoadDivisionResult();

            int currentPageIndex = info.PageIndex;
            int pageSize = info.PageSize;

            DataTable newdt = dt.Clone();

            int rowbegin = currentPageIndex * pageSize;//当前页的第一条数据在dt中的位置
            int rowend = (currentPageIndex + 1) * pageSize;//当前页的最后一条数据在dt中的位置

            if (rowbegin >= dt.Rows.Count)
            {
                return newdt;
            }

            if (rowend > dt.Rows.Count)
            {
                rowend = dt.Rows.Count;
            }

            DataView dv = dt.DefaultView;
            for (int i = rowbegin; i <= rowend - 1; i++)
            {
                newdt.ImportRow(dv[i].Row);
            }

            info.TotalRecords = dt.Rows.Count;

            return newdt;
        }

        public IEnumerable<IB_Invntory> GetSeg(string rdwayid,int? direction_id, IPagingInfo info){
            if (rdwayid == null)
                return this.Scene.Dal.Sthpms1.Select<B_Invntory>(null,info,k=>k.Beginmp);
            else if (direction_id == null)
                return this.Scene.Dal.Sthpms1.Select<B_Invntory>(p => p.Rdwayid == rdwayid,info,k=>k.Beginmp);
            else
                return this.Scene.Dal.Sthpms1.Select<B_Invntory>(p => p.Rdwayid == rdwayid && p.Direction_Dictid==direction_id, info, k => k.Beginmp);

        }
        public IEnumerable<IB_Unit> GetUnit(string rdwayid, int? direction_id, IPagingInfo info)
        {
            if (rdwayid == null)
                return this.Scene.Dal.Sthpms1.Select<B_Unit>(null, info, k => k.Beginmp);
            else if (direction_id == null)
                return this.Scene.Dal.Sthpms1.Select<B_Unit>(p => p.Rdwayid == rdwayid, info, k => k.Beginmp);
            else
                return this.Scene.Dal.Sthpms1.Select<B_Unit>(p => p.Rdwayid == rdwayid && p.Direction_Dictid == direction_id, info, k => k.Beginmp);

        }


        public void DivideRoad(string rdwayid, int? direction_Dictid=null)
        {
            string allFlag="全幅";
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;

            B_Roadway road = dao.Single<B_Roadway>(p => p.Rdwayid == rdwayid);
            if (road == null) throw new Exception("路线数据库在库不存在！");
            if (road.Endmp < road.Beginmp) throw new Exception("该路线的起点桩号大于终点桩号！");

            var rdStandard = dao.Select<B_Rdstandard>(p => p.Rdwayid == rdwayid && p.Changetype_Dictid==RdStandardTypeEnum.R211.GetEnumValue(), new DefPageInfo(), k => k.Beginmp);
            var ver=this.Scene.Bll.B_Roadway.GetNewHistoryVersion(rdwayid);
            var saveServ = new RoadSaveService();

            if (!saveServ.ValidateData(dao, rdwayid)) return;

            if (rdStandard.Count == 1)
            {
                if (rdStandard[0].Value ==allFlag )
                {
                    if (dao.Exists<B_Pmstc>(p => p.Rdwayid == rdwayid && p.Direction_Dictid != DirectionEnum.All13.GetEnumValue()))
                        throw new Exception("划分标准定义全幅路段，但路面结构有中上下行路面结构，请重新调整保持一致！");
                    if (dao.Exists<B_Sturcture>(p => p.Rdwayid == rdwayid && p.Direction_Dictid != DirectionEnum.All13.GetEnumValue()))
                        throw new Exception("划分标准定义全幅路段，但构造物有中上下行构造物，请重新调整保持一致！");

                    var allServ = MyApp.Locator.GetInstance<IRoadDividedService>() as RoadDividedService;
                    allServ.GenerateRoadSegAndUnit(dao, rdwayid, ver, DirectionEnum.All13.GetEnumValue());
                    allServ.SaveData(saveServ);
                    allServ.Dispose();
                }
                else
                {
                    if (dao.Exists<B_Pmstc>(p => p.Rdwayid == rdwayid && p.Direction_Dictid==DirectionEnum.All13.GetEnumValue()))
                        throw new Exception("划分标准没有定义全幅路段，但路面结构有中全幅路面结构，请重新调整保持一致！");
                    if (dao.Exists<B_Sturcture>(p => p.Rdwayid == rdwayid && p.Direction_Dictid == DirectionEnum.All13.GetEnumValue()))
                        throw new Exception("划分标准没有定义全幅路段，但构造物有中全幅构造物，请重新调整保持一致！");


                    var upServ = MyApp.Locator.GetInstance<IRoadDividedService>() as RoadDividedService;
                    upServ.GenerateRoadSegAndUnit(dao, rdwayid, ver, DirectionEnum.Up11.GetEnumValue());
                    upServ.SaveData(saveServ);
                    upServ.Dispose();

                    var downServ = MyApp.Locator.GetInstance<IRoadDividedService>() as RoadDividedService;
                    downServ.GenerateRoadSegAndUnit(dao, rdwayid, ver, DirectionEnum.Down12.GetEnumValue());
                    downServ.SaveData(saveServ);
                    downServ.Dispose();
                }
            }
            else
            {
                List<Stake> stakeList = new List<Stake>();
                Stake stake = null;

                foreach (var item in rdStandard)
                {
                    if (dao.Exists<B_Pmstc>(p => p.Rdwayid == rdwayid && (item.Beginmp > p.Beginmp && item.Beginmp < p.Endmp)))
                        throw new Exception("路面结构桩号没有在是否全幅桩号之间断开，请重新调整保持一致！");
                    if (dao.Exists<B_Sturcture>(p => p.Rdwayid == rdwayid && (item.Beginmp > p.Beginmp && item.Beginmp < p.Endmp)))
                        throw new Exception("构造物桩号没有在是否全幅桩号之间断开，请重新调整保持一致！");

                    if (item.Value == allFlag)
                    {
                        stake = new Stake();
                        stake.BeginMp = item.Beginmp??0;
                    }
                    else {
                        if (stake != null)
                        {
                            stake.EndMp = item.Beginmp ?? 0;
                            stakeList.Add(stake);
                        }
                        stake = null;
                    }
                }

                var upServ = MyApp.Locator.GetInstance<IRoadDividedService>() as RoadDividedService;
                upServ.GenerateRoadSegAndUnit(dao, rdwayid, ver, DirectionEnum.Up11.GetEnumValue(),true);
                upServ.SaveData(saveServ);
                upServ.Dispose();

                var downServ = MyApp.Locator.GetInstance<IRoadDividedService>() as RoadDividedService;
                downServ.GenerateRoadSegAndUnit(dao, rdwayid, ver, DirectionEnum.Down12.GetEnumValue(),true);
                downServ.SaveData(saveServ);
                downServ.Dispose();

                saveServ.SyncAllStake(dao, rdwayid,ver, stakeList);
            }


            using (IDbTransaction dbTrans = dao.BeginTransaction())
            {
                saveServ.SaveData(dao,rdwayid,ver);
                dbTrans.Commit();
            }
            saveServ.Dispose();
        }

       
        public int GetRdclass_Dictid(string unit)
        {
            return this.Scene.Dal.Sthpms1.B_Invntory.GetRdclass_Dictid(unit);
        }

        public int GetRirection_Dictid(string unit)
        {
            return this.Scene.Dal.Sthpms1.B_Invntory.GetRirection_Dictid(unit);
        }

        public string GetSegID(string unit)
        {
            return this.Scene.Dal.Sthpms1.B_Invntory.GetSegID(unit);
        }

        public List<string> List(string rdwayid)
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            return dao.Column<string>(dao.From<B_Invntory>().Select(x => x.Segid)
                         .Where(q => q.Rdwayid == rdwayid));
        }



        /// <summary>
        /// 根据测点桩号，行车方向，路线编号返回路段
        /// </summary>
        /// <param name="fwdmp">测点桩号</param>
        /// <param name="dir">调查方向</param>
        /// <param name="rdid">路线编号</param>
        /// <returns></returns>
        public string GetSegId(double fwdmp, int dir, string rdid)
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            List<B_Invntory> lst = dao.Select<B_Invntory>(x => (x.Beginmp <= fwdmp && x.Endmp >= fwdmp) && x.Direction_Dictid==dir && x.Rdwayid==rdid);
            if (lst == null)
            {
                return null;
            }
            else if (lst.Count == 0)
            {
                return null;
            }
            else
            {
                return lst[0].Segid;
            }

        }


        public List<T> GetList<T>(string rdwayid) where T : class, IB_Invntory
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            return dao.Select<T>(q => q.Rdwayid == rdwayid);
        }


        public IEnumerable<T> GetOrderByList<T>(string rdwayid, int dir) where T : class, IB_Invntory
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            dao.OpenDbConnection();
            return dao.Select<T>(q => q.Rdwayid == rdwayid && q.Direction_Dictid==dir).OrderBy(q=>q.Endmp);
        }

        public DataTable GetOrderByList(string rdwayid, int dir)
        {
            return this.Scene.Dal.Sthpms1.B_Invntory.GetOrderByList(rdwayid, dir);
        }
    }

}
